/**
 * IHIS 1.0 by HoneyBread (김민호, 이충희, 이성연, 신경민)
 * SEP 8기 KAIST
 */
package ihis.core.service;

import java.net.InetSocketAddress;
import java.util.Hashtable;
import java.util.Map;
import java.util.Scanner;

import org.apache.mina.common.ConnectFuture;
import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoSession;
import org.apache.mina.filter.LoggingFilter;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.nio.SocketConnector;
import org.apache.mina.transport.socket.nio.SocketConnectorConfig;
import org.apache.mina.util.SessionLog;

/**
 * @author minho kim
 *
 */
public class DefaultIoHandler extends IoHandlerAdapter {
	/** RequestMessage에 담을 파라메터 정보 */
	private Map parameterMap;
	
	/** parameterMap에 담을 서비스(메소드) 식별자 정보 */
	private int serviceId = -1;
	
	/** 실행 결과를 담은 객체 */
	private Object result;
	
	/** 실행 완료 여부 */
	private boolean isFinished = false;
	
	private DefaultIoHandler(){
	}
	
	public DefaultIoHandler(int serviceId, Map parameterMap){
		this.parameterMap = parameterMap;
		this.serviceId = serviceId;
	}
	
	public DefaultIoHandler(int serviceId, String key, String value){
		this.serviceId = serviceId;
		this.parameterMap = new Hashtable(1);
		parameterMap.put(key, value);
	}
	
	public DefaultIoHandler(int serviceId, String allParameterString){
		this.serviceId = serviceId;
		this.parameterMap = new Hashtable();
		
		Scanner parameters = new Scanner(allParameterString);
		parameters.useDelimiter(","); //$NON-NLS-1$
		
		while(parameters.hasNext()){
			String parameter = parameters.next();
			int index = parameter.indexOf(':'); //$NON-NLS-1$
			
			if(index != -1 && index <= parameter.length()){
				parameterMap.put(parameter.substring(0, index), parameter.substring(index+1));
			}
		}
	}
	
	@Override
	public void sessionOpened(IoSession session) throws Exception {
		RequestMessage requestMessage = new RequestMessage();
		requestMessage.setServiceId(this.serviceId);
		requestMessage.setParameter(this.parameterMap);
		session.write(requestMessage);
	}
	
	@Override
	public void messageReceived(IoSession session, Object message)
			throws Exception {
		if( (message instanceof ResponseMessage) == false){
			System.out.println("Invalid parameter in AbstractServiceCall.messageReceived()");
			return;
		}
		
		ResponseMessage responseMessage = (ResponseMessage) message;
		if(responseMessage.isOk()){
			result = responseMessage.getResult();
			SessionLog.info(session, "finish to process servcie successfully. servcie ID:" + serviceId + ")");
		} else {
			SessionLog.error(session, responseMessage.getErrorMessage());
		}
		
		setFinished(true);
	}
	
	@Override
	public void exceptionCaught(IoSession session, Throwable cause)
			throws Exception {
		cause.printStackTrace();
		session.close();
	}

	/**
	 * @return
	 */
	public Object getResult() {
		return result;
	}

	/**
	 * @param result
	 */
	public void setResult(Object result) {
		this.result = result;
	}

	/**
	 * @return
	 */
	public boolean isFinished() {
		return isFinished;
	}

	/**
	 * @param isFinished
	 */
	public void setFinished(boolean isFinished) {
		this.isFinished = isFinished;
	}
}
